﻿using System;
using Engine;
using GameEntitySystem;
using System.Collections.Generic;
using TemplatesDatabase;
using Game;

namespace IndustrialAge
{
	public partial class Comparer : IComparer<Point2>, IComparer<IChemicalItem>
	{
		public int Compare(Point2 x, Point2 y)
		{
			return x.X != y.X ? x.X.CompareTo(y.X) : x.Y.CompareTo(y.Y);
		}

		public int Compare(IChemicalItem x, IChemicalItem y)
		{
			return x.GetDispersionSystem().GetHashCode() - y.GetDispersionSystem().GetHashCode();
		}
	}

	public class SubsystemItemBlockBehavior : SubsystemThrowableBlockBehavior
	{
		public override int[] HandledBlocks => new int[] { 90, GunpowderBlock.Index, RottenMeatBlock.Index, ItemBlock.Index, TankBlock.Index };

        public override bool OnAim(Ray3 aim, ComponentMiner componentMiner, AimState state)
        {
			int value = componentMiner.ActiveBlockValue;
			if (!(BlocksManager.Blocks[Terrain.ExtractContents(value)] is ItemBlock block))
				return false;
			var item = block.GetItem(ref value);
			return Terrain.ExtractContents(value) != GunpowderBlock.Index && (item is OreChunk || item is Mould && (value != ItemBlock.IdTable["Telescope"]) && (value != ItemBlock.IdTable["Screwdriver"]) || item is Brick || value == ItemBlock.IdTable["ScrapIron"]) && base.OnAim(aim, componentMiner, state);
		}
        public override bool OnUse(Ray3 ray, ComponentMiner componentMiner)
        {
			int activeBlockValue = componentMiner.ActiveBlockValue;
			TerrainRaycastResult? result = componentMiner.Raycast<TerrainRaycastResult>(ray,RaycastMode.Digging);
			Entity entity;
			Vector3 position;
			BodyRaycastResult? body;
			if (activeBlockValue == ItemBlock.IdTable["Wrench"])
			{
				body = (BodyRaycastResult)componentMiner.Raycast(ray,RaycastMode.Interaction,false,true,false);
				Matrix matrix = componentMiner.ComponentCreature.ComponentBody.Matrix;
				position = matrix.Translation + 1f * matrix.Forward + Vector3.UnitY;
				if (body.HasValue && (!result.HasValue || body.Value.Distance < result.Value.Distance))
				{
					entity = body.Value.ComponentBody.Entity;
					if (entity.FindComponent<ComponentTrain>() != null || entity.FindComponent<ComponentBoatI>() != null || entity.FindComponent<ComponentBoat>() != null || entity.FindComponent<ComponentRocket>() != null || entity.FindComponent<ComponentAutoTank>() != null)
					{
						for (var i = entity.FindComponents<IInventory>().GetEnumerator(); i.MoveNext();)
							i.Current.DropAllItems(position);
						if (entity.ValuesDictionary.DatabaseObject.Name == "S-100")
						{
							Utils.SubsystemPickables.AddPickable(ItemBlock.IdTable["AutoTank"], 1, position, null, null);
							Project.RemoveEntity(entity, true);
							return true;
						}

						Utils.SubsystemPickables.AddPickable(ItemBlock.IdTable[entity.ValuesDictionary.DatabaseObject.Name.Length == 8 ? "Minecart" : entity.ValuesDictionary.DatabaseObject.Name], 1, position, null, null);
						Project.RemoveEntity(entity, true);
						return true;
					}
				}
			}
			else if (activeBlockValue == ItemBlock.IdTable["灭火器"])
			{
				//result = componentMiner.PickTerrainForDigging(start, direction);
				if (result.HasValue)
				{
					for (int ii = 0; ii < 6; ii++)
					{
						Point3 fac = CellFace.FaceToPoint3(ii);
						Point3 point = result.Value.CellFace.Point + fac;

						int value2 = Utils.Terrain.GetCellValueFast(point.X, point.Y, point.Z);
						int value3 = Utils.Terrain.GetCellContentsFast(point.X, point.Y, point.Z);
						if (value3 == FireBlock.Index)
						{
							//Utils.SubsystemTerrain.DestroyCell(5, point.X, point.Y, point.Z, 0, true, false);
							Utils.SubsystemTerrain.ChangeCell(point.X, point.Y, point.Z, 0);
						}
					}
				}
				Utils.SubsystemParticles.AddParticleSystem(new GunSmokeParticleSystem(SubsystemTerrain, ray.Position, ray.Direction));
				return true;
			}
			else if (activeBlockValue == ItemBlock.IdTable["金属探测器"])
			{
				float dis = 999f;
				int numm = 0;
				for (int i = -10; i < 10; i++)
					for (int j = -10; j < 10; j++)
						for (int k = -10; k < 10; k++)
						{
							Point3 point = new Point3((int)ray.Position.X + i, (int)ray.Position.Y + j, (int)ray.Position.Z + k);
							int value2 = Utils.Terrain.GetCellValueFast(point.X, point.Y, point.Z);
							int value3 = Utils.Terrain.GetCellContentsFast(point.X, point.Y, point.Z);
							var block = BlocksManager.Blocks[Terrain.ExtractContents(value2)];
							if (block.BlockIndex == BasaltBlock.Index && value2 != BasaltBlock.Index && value2 != 536870979 && value2 != 1073741891 && value2 != 1610612803)
							{
								if (dis > i * i + j * j + k * k)
								{
									dis = i * i + j * j + k * k;
								}
								numm += 1;
							}
							if ((block.BlockIndex == IronOreBlock.Index || block.BlockIndex == CopperOreBlock.Index || block.BlockIndex == GermaniumOreBlock.Index || block.BlockIndex == ElementBlock.Index || block.BlockIndex == IronBlock.Index || block.BlockIndex == IronDoorBlock.Index || block.BlockIndex == IronFenceBlock.Index || block.BlockIndex == IronFenceGateBlock.Index || block.BlockIndex == IronLadderBlock.Index || block.BlockIndex == CopperBlock.Index || block.BlockIndex == EngineBlock.Index || block.BlockIndex == PresserBlock.Index || block.BlockIndex == KibblerBlock.Index || block.BlockIndex == PresserNNBlock.Index || block.BlockIndex == SqueezerBlock.Index || block.BlockIndex == CastMachBlock.Index || block.BlockIndex == BlastFurnaceBlock.Index || block.BlockIndex == HearthFurnaceBlock.Index || block.BlockIndex == FireBoxBlock.Index || block.BlockIndex == FurnaceNBlock.Index || block.BlockIndex == CrusherBlock.Index || block.BlockIndex == DrillerBlock.Index || block.BlockIndex == LiquidPumpBlock.Index))
							{
								if (dis > i * i + j * j + k * k)
								{
									dis = i * i + j * j + k * k;
								}
								numm += 1;
							}
						}
				if (dis == 999f && numm == 0)
				{
					componentMiner.ComponentPlayer.ComponentGui.DisplaySmallMessage("No Metal Mineral in Range",Color.White, blinking: true, playNotificationSound: true);
				}
				else
					componentMiner.ComponentPlayer.ComponentGui.DisplaySmallMessage("Mineral in Range:" + numm.ToString() + " Nearest Mineral Distance: " + MathF.Sqrt(dis).ToString(),Color.White, blinking: true, playNotificationSound: true);
				return true;
			}
			else if ((activeBlockValue == ItemBlock.IdTable["Train"] || activeBlockValue == ItemBlock.IdTable["Minecart"] || activeBlockValue == ItemBlock.IdTable["ETrain"]) && result.HasValue && Terrain.ExtractContents(result.Value.Value) == RailBlock.Index)
			{
				position = new Vector3(result.Value.CellFace.Point) + new Vector3(0.5f);
				entity = DatabaseManager.CreateEntity(Project, activeBlockValue == ItemBlock.IdTable["Minecart"] ? "Carriage" : activeBlockValue == ItemBlock.IdTable["Train"] ? "Train" : "ETrain", true);

				var rotation = componentMiner.ComponentCreature.ComponentCreatureModel.EyeRotation.GetForwardVector();
				entity.FindComponent<ComponentTrain>(true).SetDirection(RailBlock.IsDirectionX(RailBlock.GetRailType(Terrain.ExtractData(result.Value.Value)))
					? rotation.Z < 0 ? 0 : 2
					: rotation.X < 0 ? 1 : 3);
				entity.FindComponent<ComponentBody>(true).Position = position;
				entity.FindComponent<ComponentSpawn>(true).SpawnDuration = 0f;
				Project.AddEntity(entity);
				var componentTrain = entity.FindComponent<ComponentTrain>(true);
				if (activeBlockValue == ItemBlock.IdTable["Minecart"])
				{
					componentTrain.Update(0);
					var train = componentTrain.FindNearestTrain();
					if (train != null)
						componentTrain.ParentBody = train;
				}
				componentMiner.RemoveActiveTool(1);
				Utils.SubsystemAudio.PlaySound("Audio/BlockPlaced", 1f, 0f, position, 3f, true);
				return true;
			}
			else if (activeBlockValue == ItemBlock.IdTable["Telescope"])
			{
				//ScreensManager.SwitchScreen(new RecipaediaScreen2());
				var view = componentMiner.ComponentPlayer.GameWidget;
				view.ActiveCamera = view.ActiveCamera is TelescopeCamera ? view.FindCamera<FppCamera>(true) : (Camera)new TelescopeCamera(view);
				return true;
			}
			else if (activeBlockValue == ItemBlock.IdTable["测距仪"])
			{
				Vector3 eyePosition = componentMiner.ComponentCreature.ComponentCreatureModel.EyePosition;
				Matrix matrix = componentMiner.ComponentCreature.ComponentBody.Matrix;
				ComponentNPlayer miner2 = componentMiner.Entity.FindComponent<ComponentNPlayer>();
				Vector3 vectorp = eyePosition + matrix.Right * 0.3f - matrix.Up * 0.2f;
				//componentMiner.ComponentPlayer?.ComponentGui.DisplaySmallMessage((99999999).ToString(), blinking: true, playNotificationSound: false);
				result = miner2.PickTerrainForDigging2(vectorp, ray.Direction, 200f);
				body = miner2.PickBody2(vectorp, ray.Direction, 200f);

				//componentMiner.ComponentPlayer?.ComponentGui.DisplaySmallMessage((11111111).ToString(), blinking: true, playNotificationSound: false);
				float end = 100f;
				if (body.HasValue && (!result.HasValue || body.Value.Distance < result.Value.Distance))
				{
					//ComponentCreature cre1 = body.Value.ComponentBody.Entity.FindComponent<ComponentCreature>();
					//if (cre1 != null)
					//{
					componentMiner.ComponentPlayer.ComponentGui.DisplaySmallMessage("Distance  " + body.Value.Distance.ToString(), Color.White, blinking: true, playNotificationSound: true);
					return true;
					//}
				}
				else if (result.HasValue)
				{
					componentMiner.ComponentPlayer.ComponentGui.DisplaySmallMessage("Distance  " + result.Value.Distance.ToString(), Color.White, blinking: true, playNotificationSound: true);
					return true;

				}
				componentMiner.ComponentPlayer.ComponentGui.DisplaySmallMessage("Distance Error ", Color.White, blinking: true, playNotificationSound: true);
				//ScreensManager.SwitchScreen(new RecipaediaScreen2());
				//var view = componentMiner.ComponentPlayer.View;
				//view.ActiveCamera = view.ActiveCamera is TelescopeCamera ? view.FindCamera<FppCamera>(true) : (Camera)new TelescopeCamera(view);
				return true;
			}
			else if (activeBlockValue == ItemBlock.IdTable["遥控器"])
			{
				var view = componentMiner.ComponentPlayer.GameWidget;
				ComponentNPlayer miner2 = componentMiner.Entity.FindComponent<ComponentNPlayer>();
				if (view.ActiveCamera is DebugCamera2)
				{

					TerrainRaycastResult? terrainRaycastResult = Utils.SubsystemTerrain.Raycast(view.m_activeCamera.ViewPosition, view.m_activeCamera.ViewPosition + new Vector3(0f, -200f, 0f), false, true, (value, distance) => !(Terrain.ExtractContents(value) == 0 || Terrain.ExtractContents(value) == GlassBlock.Index));
					//BodyRaycastResult? bodyrr= Utils.SubsystemBodies.Raycast(view.m_activeCamera.ViewPosition, view.m_activeCamera.ViewPosition + new Vector3(0f, -200f, 0f), 0.35f, null);
					BodyRaycastResult? bodyrr = miner2.PickBody2(view.m_activeCamera.ViewPosition, view.m_activeCamera.ViewDirection, 200f);
					//Utils.SubsystemLaser.MakeLightningStrike(view.m_activeCamera.ViewPosition, view.m_activeCamera.ViewPosition + new Vector3(0f, -200f, 0f));
					if (bodyrr != null)
					{
						ComponentCreature cre1 = bodyrr.Value.ComponentBody.Entity.FindComponent<ComponentCreature>();
						if (cre1 != null)
						{
							for (int iii = 0; iii < Utils.SubsystemSour.m_radio.Count; iii++)
							{
								if (Utils.SubsystemSour.m_radio.Array[iii].W == 777)
								{
									Utils.SubsystemSour.m_radio.Remove(Utils.SubsystemSour.m_radio.Array[iii]);
									break;
								}
							}
							var e1 = Utils.SubsystemBodies.Bodies.GetEnumerator();
							while (e1.MoveNext())
							{
								var entity2 = e1.Current.Entity;
								//var entity = 0;
								ComponentCreature cre2 = entity2.FindComponent<ComponentCreature>();
								if (cre2 != null && entity2.FindComponent<ComponentNPlayer>() == null && entity2.FindComponent<ComponentHealth>().Health > 0 && cre2.DisplayName == "S-100")
								{

									cre2.Entity.FindComponent<ComponentChaseBehavior>().Attack(cre1, 100f * 2, 999f * 2, true);
								}
							}
							//Utils.SubsystemSour.m_radio.Add(new Vector4(bodyrr.Value.ComponentBody.Position.X, bodyrr.Value.ComponentBody.Position.Y, bodyrr.Value.ComponentBody.Position.Z, 777));
							componentMiner.ComponentPlayer.ComponentGui.DisplaySmallMessage("STarget Set  " + cre1.DisplayName.ToString(), Color.White, blinking: true, playNotificationSound: true);
							//componentMiner.ComponentPlayer.ComponentGui.DisplaySmallMessage("STarget Set  " + bodyrr.Value.ComponentBody.Position.Y.ToString(), blinking: true, playNotificationSound: true);
							return true;
						}
					}
					else
						componentMiner.ComponentPlayer.ComponentGui.DisplaySmallMessage("Move Forword", Color.White, blinking: true, playNotificationSound: true);
					if (terrainRaycastResult.HasValue)
					{
						for (int iii = 0; iii < Utils.SubsystemSour.m_radio.Count; iii++)
						{
							if (Utils.SubsystemSour.m_radio.Array[iii].W == 888)
							{
								Utils.SubsystemSour.m_radio.Remove(Utils.SubsystemSour.m_radio.Array[iii]);
								break;
							}
						}

						var e1 = Utils.SubsystemBodies.Bodies.GetEnumerator();
						while (e1.MoveNext())
						{
							var entity2 = e1.Current.Entity;
							//var entity = 0;
							ComponentCreature cre2 = entity2.FindComponent<ComponentCreature>();
							if (cre2 != null && entity2.FindComponent<ComponentNPlayer>() == null && entity2.FindComponent<ComponentHealth>().Health > 0 && cre2.DisplayName == "S-100")
							{

								cre2.Entity.FindComponent<ComponentPathfinding>().SetDestination(new Vector3(terrainRaycastResult.Value.CellFace.X, terrainRaycastResult.Value.CellFace.Y, terrainRaycastResult.Value.CellFace.Z), 1f, 1f, 0, useRandomMovements: false, ignoreHeightDifference: true, raycastDestination: false, null);
							}
						}

						//Utils.SubsystemSour.m_radio.Add(new Vector4(terrainRaycastResult.Value.CellFace.X, terrainRaycastResult.Value.CellFace.Y, terrainRaycastResult.Value.CellFace.Z, 888));
					}
					//componentMiner.ComponentPlayer.ComponentGui.DisplaySmallMessage("Set Position" + terrainRaycastResult.Value.CellFace.ToString(), blinking: true, playNotificationSound: true);
					return false;
				}
				Vector3 eyePosition = componentMiner.ComponentCreature.ComponentCreatureModel.EyePosition;
				Matrix matrix = componentMiner.ComponentCreature.ComponentBody.Matrix;

				Vector3 vectorp = eyePosition + matrix.Right * 0.3f - matrix.Up * 0.2f;
				//componentMiner.ComponentPlayer?.ComponentGui.DisplaySmallMessage((99999999).ToString(), blinking: true, playNotificationSound: false);
				result = miner2.PickTerrainForDigging2(vectorp, ray.Direction, 200f);
				body = miner2.PickBody2(vectorp, ray.Direction, 200f);
				//Utils.SubsystemLaser.MakeLightningStrike(view.m_activeCamera.ViewPosition, view.m_activeCamera.ViewPosition + new Vector3(0f, -200f, 0f));
				//componentMiner.ComponentPlayer?.ComponentGui.DisplaySmallMessage((11111111).ToString(), blinking: true, playNotificationSound: false);
				float end = 100f;
				if (body.HasValue && (!result.HasValue || body.Value.Distance < result.Value.Distance))
				{

					ComponentCreature cre1 = body.Value.ComponentBody.Entity.FindComponent<ComponentCreature>();
					if (cre1 != null)
					{
						for (int iii = 0; iii < Utils.SubsystemSour.m_radio.Count; iii++)
						{
							if (Utils.SubsystemSour.m_radio.Array[iii].W == 777)
							{
								Utils.SubsystemSour.m_radio.Remove(Utils.SubsystemSour.m_radio.Array[iii]);
								break;
							}
						}
						var e1 = Utils.SubsystemBodies.Bodies.GetEnumerator();
						while (e1.MoveNext())
						{
							var entity2 = e1.Current.Entity;
							//var entity = 0;
							ComponentCreature cre2 = entity2.FindComponent<ComponentCreature>();
							if (cre2 != null && entity2.FindComponent<ComponentNPlayer>() == null && entity2.FindComponent<ComponentHealth>().Health > 0 && cre2.DisplayName == "S-100")
							{

								cre2.Entity.FindComponent<ComponentChaseBehavior>().Attack(cre1, 100f * 2, 999f * 2, true);
							}
						}
						componentMiner.ComponentPlayer.ComponentGui.DisplaySmallMessage("Target Set  " + cre1.DisplayName.ToString(), Color.White, blinking: true, playNotificationSound: true);
						//componentMiner.ComponentPlayer.ComponentGui.DisplaySmallMessage("Target Set  " + body.Value.ComponentBody.Position.Y.ToString(), blinking: true, playNotificationSound: true);
						return true;
					}
				}
				else
					componentMiner.ComponentPlayer.ComponentGui.DisplaySmallMessage("Move Forward", Color.White, blinking: true, playNotificationSound: true);
				TerrainRaycastResult? terrainRaycastResult2 = Utils.SubsystemTerrain.Raycast(view.m_activeCamera.ViewPosition, view.m_activeCamera.ViewPosition + view.ActiveCamera.ViewDirection * 100f, false, true, (value, distance) => !(Terrain.ExtractContents(value) == 0 || Terrain.ExtractContents(value) == GlassBlock.Index));
				if (terrainRaycastResult2.HasValue)
				{
					for (int iii = 0; iii < Utils.SubsystemSour.m_radio.Count; iii++)
					{
						if (Utils.SubsystemSour.m_radio.Array[iii].W == 888)
						{
							Utils.SubsystemSour.m_radio.Remove(Utils.SubsystemSour.m_radio.Array[iii]);
							break;
						}
					}
					var e1 = Utils.SubsystemBodies.Bodies.GetEnumerator();
					while (e1.MoveNext())
					{
						var entity2 = e1.Current.Entity;
						//var entity = 0;
						ComponentCreature cre2 = entity2.FindComponent<ComponentCreature>();
						if (cre2 != null && entity2.FindComponent<ComponentNPlayer>() == null && entity2.FindComponent<ComponentHealth>().Health > 0 && cre2.DisplayName == "S-100")
						{

							cre2.Entity.FindComponent<ComponentPathfinding>().SetDestination(new Vector3(terrainRaycastResult2.Value.CellFace.X, terrainRaycastResult2.Value.CellFace.Y, terrainRaycastResult2.Value.CellFace.Z), 1f, 1f, 0, useRandomMovements: false, ignoreHeightDifference: true, raycastDestination: false, null);
						}
					}
					//componentMiner.ComponentPlayer.ComponentGui.DisplaySmallMessage("Move Forward", blinking: true, playNotificationSound: true);
				}
				//componentMiner.ComponentPlayer.ComponentGui.DisplaySmallMessage("Move Forward", blinking: true, playNotificationSound: true);
				//componentMiner.ComponentPlayer.ComponentGui.DisplaySmallMessage("Set Position" + terrainRaycastResult2.Value.CellFace.ToString(), blinking: true, playNotificationSound: true);
				return true;
			}
			else if (activeBlockValue == ItemBlock.IdTable["卫星连接器"])
			{
				bool find = false;
				for (int iii = 0; iii < Utils.SubsystemSour.m_radio.Count; iii++)
				{
					if (Utils.SubsystemSour.m_radio.Array[iii].W == 12345)
					{
						find = true;
						break;
					}
				}
				if (find)
				{
					var view = componentMiner.ComponentPlayer.GameWidget;
					if (!(view.ActiveCamera is DebugCamera2))
						componentMiner.ComponentPlayer.ComponentGui.DisplaySmallMessage("Satellite Connected  " + componentMiner.ComponentPlayer.GameWidget.ActiveCamera.ViewPosition.ToString(), Color.White, blinking: true, playNotificationSound: true);
					view.ActiveCamera = view.ActiveCamera is DebugCamera2 ? view.FindCamera<FppCamera>(true) : (Camera)new DebugCamera2(view);
					return true;

				}
				else
				{
					componentMiner.ComponentPlayer.ComponentGui.DisplaySmallMessage("No Satellite Found", Color.White, blinking: true, playNotificationSound: true);
				}
				//ScreensManager.SwitchScreen(new RecipaediaScreen2());

			}
			/*else if (activeBlockValue == ItemBlock.IdTable["Minecart"])
			{
				entity = DatabaseManager.CreateEntity(Project, "Carriage", true);
				body = componentMiner.PickBody(start, direction);
				if (body.HasValue && (!result.HasValue || body.Value.Distance < result.Value.Distance))
				{
					body = componentMiner.PickBody(start, direction);
					var componentTrain = entity.FindComponent<ComponentTrain>(true);
					var train = body.Value.ComponentBody.Entity.FindComponent<ComponentTrain>();
					if (train != null)
						componentTrain.ParentBody = train;
				}
				else if (result.HasValue)
					position = result.Value.RaycastStart + Vector3.Normalize(result.Value.RaycastEnd - result.Value.RaycastStart) * result.Value.Distance; ;
				var rotation = componentMiner.ComponentCreature.ComponentCreatureModel.EyeRotation.GetForwardVector();
				entity.FindComponent<ComponentTrain>(true).SetDirection(RailBlock.IsDirectionX(RailBlock.GetRailType(Terrain.ExtractData(result.Value.Value)))
					? rotation.Z < 0 ? 0 : 2
					: rotation.X < 0 ? 1 : 3);
				goto put;
			}*/
			if (activeBlockValue == ItemBlock.IdTable["基因查看器"] || Terrain.ExtractContents(activeBlockValue) == TankBlock.Index)
			{
				body = componentMiner.Raycast<BodyRaycastResult>(ray,RaycastMode.Interaction,false,true,false);
				if (body.HasValue && (!result.HasValue || body.Value.Distance < result.Value.Distance))
				{
					var cv = body.Value.ComponentBody.Entity.FindComponent<ComponentVariant>();
					if (cv != null)
					{
						if (Terrain.ExtractContents(activeBlockValue) == TankBlock.Index)
						{
							int data = Terrain.ExtractData(activeBlockValue);
							if (data != 0)
							{
								float v = TankBlock.GetFactor(data);
								ref float val = ref cv.Genome.DominantGenes[(int)TankBlock.GetTrait(data)];
								if (v == 1f)
									val += 0.1f;
								else
									val *= v;
								cv.OnEntityAdded();
								return true;
							}
						}
						GameWidget gameWidget = componentMiner.ComponentPlayer.GameWidget;
						DialogsManager.ShowDialog(gameWidget, new MessageDialog("Result", cv.Genome.ToString(), "OK", null, null)
						{
							Size = gameWidget.ActualSize * 0.8f
						});
					}
					return true;
				}



			}

			if (activeBlockValue == ItemBlock.IdTable["Back"] && !result.HasValue)
			{
				//if (result.HasValue)

				//position = result.Value.RaycastStart + Vector3.Normalize(result.Value.RaycastEnd - result.Value.RaycastStart) * result.Value.Distance;
				entity = DatabaseManager.CreateEntity(Project, "Back", true);
				entity.FindComponent<ComponentFrame>(true).Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, 0f);

				body = componentMiner.Raycast<BodyRaycastResult>(ray,RaycastMode.Interaction,false,true,false);
				if (body.HasValue && (!result.HasValue || body.Value.Distance < result.Value.Distance) && body.Value.ComponentBody.Entity.FindComponent<ComponentRocket>() != null && body.Value.ComponentBody.Mass == 2500 && body.Value.ComponentBody.ChildBodies.Count == 0)
				{

					entity.FindComponent<ComponentBody>(true).Position = body.Value.ComponentBody.Position + new Vector3(0f, 6.5f, 0f);
					entity.FindComponent<ComponentSpawn>(true).SpawnDuration = 0f;
					Project.AddEntity(entity);
					//if (body.Value.ComponentBody.m_childBodies.Count==0)
					//entity.FindComponent<ComponentRider>().StartMounting(body.Value.ComponentBody.Entity.FindComponent<ComponentMount>());

					entity.FindComponent<ComponentBody>(true).ParentBody = body.Value.ComponentBody;
					entity.FindComponent<ComponentBody>(true).ParentBodyPositionOffset = Vector3.Transform(entity.FindComponent<ComponentBody>(true).Position - body.Value.ComponentBody.Entity.FindComponent<ComponentMount>().ComponentBody.Position, Quaternion.Conjugate(body.Value.ComponentBody.Entity.FindComponent<ComponentMount>().ComponentBody.Rotation));
					entity.FindComponent<ComponentBody>(true).ParentBodyRotationOffset = Quaternion.Conjugate(body.Value.ComponentBody.Entity.FindComponent<ComponentMount>().ComponentBody.Rotation) * entity.FindComponent<ComponentBody>(true).Rotation;

					componentMiner.RemoveActiveTool(1);
					//Utils.SubsystemAudio.PlaySound("Audio/BlockPlaced", 1f, 0f, position, 3f, true);
					return true;
				}

				return false;
			}
			if (activeBlockValue == ItemBlock.IdTable["Rocket3"] && !result.HasValue)
			{
				//position = result.Value.RaycastStart + Vector3.Normalize(result.Value.RaycastEnd - result.Value.RaycastStart) * result.Value.Distance;
				entity = DatabaseManager.CreateEntity(Project, "Rocket3", true);
				entity.FindComponent<ComponentFrame>(true).Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, 0f);

				body = componentMiner.Raycast<BodyRaycastResult>(ray,RaycastMode.Interaction,false,true,false);
				if (body.HasValue && (!result.HasValue || body.Value.Distance < result.Value.Distance) && body.Value.ComponentBody.Entity.FindComponent<ComponentRocket>() != null && body.Value.ComponentBody.Mass == 2500 && body.Value.ComponentBody.ChildBodies.Count == 0)
				{

					entity.FindComponent<ComponentBody>(true).Position = body.Value.ComponentBody.Position + new Vector3(0f, 6f, 0f);
					entity.FindComponent<ComponentSpawn>(true).SpawnDuration = 0f;
					Project.AddEntity(entity);
					//if (body.Value.ComponentBody.m_childBodies.Count==0)
					//entity.FindComponent<ComponentRider>().StartMounting(body.Value.ComponentBody.Entity.FindComponent<ComponentMount>());

					entity.FindComponent<ComponentBody>(true).ParentBody = body.Value.ComponentBody;
					entity.FindComponent<ComponentBody>(true).ParentBodyPositionOffset = Vector3.Transform(entity.FindComponent<ComponentBody>(true).Position - body.Value.ComponentBody.Entity.FindComponent<ComponentMount>().ComponentBody.Position, Quaternion.Conjugate(body.Value.ComponentBody.Entity.FindComponent<ComponentMount>().ComponentBody.Rotation));
					entity.FindComponent<ComponentBody>(true).ParentBodyRotationOffset = Quaternion.Conjugate(body.Value.ComponentBody.Entity.FindComponent<ComponentMount>().ComponentBody.Rotation) * entity.FindComponent<ComponentBody>(true).Rotation;

					componentMiner.RemoveActiveTool(1);
					//Utils.SubsystemAudio.PlaySound("Audio/BlockPlaced", 1f, 0f, position, 3f, true);
					return true;
				}
				return false;
				//goto put;
			}

			else if (result.HasValue)
			{
				position = result.Value.HitPoint();
				if (activeBlockValue == ItemBlock.IdTable["SteamBoat"])
				{
					entity = DatabaseManager.CreateEntity(Project, "SteamBoat", true);
					entity.FindComponent<ComponentFrame>(true).Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, 0f);
					goto put;
				}
				if (activeBlockValue == ItemBlock.IdTable["Rocket"])
				{
					entity = DatabaseManager.CreateEntity(Project, "Rocket", true);
					entity.FindComponent<ComponentFrame>(true).Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, 0f);
					goto put;
				}
				if (activeBlockValue == ItemBlock.IdTable["Back"])
				{
					//if (result.HasValue)

					//position = result.Value.RaycastStart + Vector3.Normalize(result.Value.RaycastEnd - result.Value.RaycastStart) * result.Value.Distance;
					entity = DatabaseManager.CreateEntity(Project, "Back", true);
					entity.FindComponent<ComponentFrame>(true).Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, 0f);

					body = componentMiner.Raycast<BodyRaycastResult>(ray,RaycastMode.Interaction,false,true,false);
					if (body.HasValue && (!result.HasValue || body.Value.Distance < result.Value.Distance) && body.Value.ComponentBody.Entity.FindComponent<ComponentRocket>() != null && body.Value.ComponentBody.Mass == 2500 && body.Value.ComponentBody.ChildBodies.Count == 0)
					{

						entity.FindComponent<ComponentBody>(true).Position = body.Value.ComponentBody.Position + new Vector3(0f, 6.5f, 0f);
						entity.FindComponent<ComponentSpawn>(true).SpawnDuration = 0f;
						Project.AddEntity(entity);
						//if (body.Value.ComponentBody.m_childBodies.Count==0)
						//entity.FindComponent<ComponentRider>().StartMounting(body.Value.ComponentBody.Entity.FindComponent<ComponentMount>());

						entity.FindComponent<ComponentBody>(true).ParentBody = body.Value.ComponentBody;
						entity.FindComponent<ComponentBody>(true).ParentBodyPositionOffset = Vector3.Transform(entity.FindComponent<ComponentBody>(true).Position - body.Value.ComponentBody.Entity.FindComponent<ComponentMount>().ComponentBody.Position, Quaternion.Conjugate(body.Value.ComponentBody.Entity.FindComponent<ComponentMount>().ComponentBody.Rotation));
						entity.FindComponent<ComponentBody>(true).ParentBodyRotationOffset = Quaternion.Conjugate(body.Value.ComponentBody.Entity.FindComponent<ComponentMount>().ComponentBody.Rotation) * entity.FindComponent<ComponentBody>(true).Rotation;

						componentMiner.RemoveActiveTool(1);
						//Utils.SubsystemAudio.PlaySound("Audio/BlockPlaced", 1f, 0f, position, 3f, true);
						return true;
					}

					goto put;
				}
				if (activeBlockValue == ItemBlock.IdTable["Rocket3"])
				{
					//position = result.Value.RaycastStart + Vector3.Normalize(result.Value.RaycastEnd - result.Value.RaycastStart) * result.Value.Distance;
					entity = DatabaseManager.CreateEntity(Project, "Rocket3", true);
					entity.FindComponent<ComponentFrame>(true).Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, 0f);

					body = componentMiner.Raycast<BodyRaycastResult>(ray, RaycastMode.Interaction, false, true, false);
					if (body.HasValue && (!result.HasValue || body.Value.Distance < result.Value.Distance) && body.Value.ComponentBody.Entity.FindComponent<ComponentRocket>() != null && body.Value.ComponentBody.Mass == 2500 && body.Value.ComponentBody.ChildBodies.Count == 0)
					{

						entity.FindComponent<ComponentBody>(true).Position = body.Value.ComponentBody.Position + new Vector3(0f, 6f, 0f);
						entity.FindComponent<ComponentSpawn>(true).SpawnDuration = 0f;
						Project.AddEntity(entity);
						//if (body.Value.ComponentBody.m_childBodies.Count==0)
						//entity.FindComponent<ComponentRider>().StartMounting(body.Value.ComponentBody.Entity.FindComponent<ComponentMount>());

						entity.FindComponent<ComponentBody>(true).ParentBody = body.Value.ComponentBody;
						entity.FindComponent<ComponentBody>(true).ParentBodyPositionOffset = Vector3.Transform(entity.FindComponent<ComponentBody>(true).Position - body.Value.ComponentBody.Entity.FindComponent<ComponentMount>().ComponentBody.Position, Quaternion.Conjugate(body.Value.ComponentBody.Entity.FindComponent<ComponentMount>().ComponentBody.Rotation));
						entity.FindComponent<ComponentBody>(true).ParentBodyRotationOffset = Quaternion.Conjugate(body.Value.ComponentBody.Entity.FindComponent<ComponentMount>().ComponentBody.Rotation) * entity.FindComponent<ComponentBody>(true).Rotation;

						componentMiner.RemoveActiveTool(1);
						Utils.SubsystemAudio.PlaySound("Audio/BlockPlaced", 1f, 0f, position, 3f, true);
						return true;
					}
					//return false;
					goto put;
				}
				if (activeBlockValue == ItemBlock.IdTable["QST"])
				{
					entity = DatabaseManager.CreateEntity(Project, "Submarine", true);
					entity.FindComponent<ComponentFrame>(true).Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, 0f);
					goto put;
				}
				else if (activeBlockValue == ItemBlock.IdTable["Icebreaker"])
				{
					entity = DatabaseManager.CreateEntity(Project, "Icebreaker", true);
					entity.FindComponent<ComponentFrame>(true).Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, 0f);
					goto put;
				}
				else if (activeBlockValue == ItemBlock.IdTable["AutoTank"])
				{
					entity = DatabaseManager.CreateEntity(Project, "S-100", true);
					entity.FindComponent<ComponentFrame>(true).Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, 0f);
					goto put;
				}
				else if (activeBlockValue == ItemBlock.IdTable["MGun"])
				{
					entity = DatabaseManager.CreateEntity(Project, "MGun", true);
					entity.FindComponent<ComponentFrame>(true).Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, m_random.Float(0f, 6.283185f));
					goto put;
				}
				else if (activeBlockValue == ItemBlock.IdTable["Cannonw"])
				{
					entity = DatabaseManager.CreateEntity(Project, "Cannonw", true);
					entity.FindComponent<ComponentFrame>(true).Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, m_random.Float(0f, 6.283185f));
					goto put;
				}
				else if (activeBlockValue == ItemBlock.IdTable["Airship"])
				{
					entity = DatabaseManager.CreateEntity(Project, "Airship", true);
					entity.FindComponent<ComponentFrame>(true).Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, m_random.Float(0f, 6.283185f));
					goto put;
				}
				else if (activeBlockValue == ItemBlock.IdTable["Airship"])
				{
					entity = DatabaseManager.CreateEntity(Project, "Airship", true);
					entity.FindComponent<ComponentFrame>(true).Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, m_random.Float(0f, 6.283185f));
					goto put;
				}
				else if (activeBlockValue == ItemBlock.IdTable["Plane"])
				{
					entity = DatabaseManager.CreateEntity(Project, "Plane", true);
					entity.FindComponent<ComponentFrame>(true).Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, m_random.Float(0f, 6.283185f));
					goto put;
				}
				else if (activeBlockValue == ItemBlock.IdTable["Tank"])
				{
					entity = DatabaseManager.CreateEntity(Project, "Tank", true);
					entity.FindComponent<ComponentFrame>(true).Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, m_random.Float(0f, 6.283185f));
					//entity.FindComponent<ComponentCar>(true).Load;
					goto put;
				}
				else if (activeBlockValue == ItemBlock.IdTable["Car"])
				{
					entity = DatabaseManager.CreateEntity(Project, "Car", true);
					entity.FindComponent<ComponentFrame>(true).Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, m_random.Float(0f, 6.283185f));
					goto put;
				}
				else if (activeBlockValue == ItemBlock.IdTable["Tractor"])
				{
					entity = DatabaseManager.CreateEntity(Project, "Tractor", true);
					entity.FindComponent<ComponentFrame>(true).Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, m_random.Float(0f, 6.283185f));
					goto put;
				}
				else if (activeBlockValue == ItemBlock.IdTable["Digger"])
				{
					entity = DatabaseManager.CreateEntity(Project, "Digger", true);
					entity.FindComponent<ComponentFrame>(true).Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, m_random.Float(0f, 6.283185f));
					goto put;
				}
				else if (activeBlockValue == ItemBlock.IdTable["Pavior"])
				{
					entity = DatabaseManager.CreateEntity(Project, "Pavior", true);
					entity.FindComponent<ComponentFrame>(true).Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, m_random.Float(0f, 6.283185f));
					goto put;
				}
				else if (BlocksManager.Blocks[Terrain.ExtractContents(activeBlockValue)] is ItemBlock item && item.GetItem(ref activeBlockValue) is Mine mine)
				{
					entity = DatabaseManager.CreateEntity(Project, "Mine", new ValuesDictionary
					{
						{ "Mine", new ValuesDictionary { { "Type", mine.MineType } } }
					}, true);
					entity.FindComponent<ComponentFrame>(true).Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, m_random.Float(0f, 6.283185f));
					var componentMine = entity.FindComponent<ComponentMine>(true);
					componentMine.ExplosionPressure = mine.ExplosionPressure;
					componentMine.Delay = mine.Delay;
					goto put;
				}
			}
			IInventory inventory = componentMiner.Inventory;
			TerrainRaycastResult? result2;
			if (Terrain.ExtractContents(activeBlockValue) == 90)
			{
				result2 = componentMiner.Raycast<TerrainRaycastResult>(ray,RaycastMode.Gathering);
				if (result2.HasValue)
				{
					CellFace cellFace = result2.Value.CellFace;
					int cellValue = Terrain.ReplaceLight(Utils.Terrain.GetCellValue(cellFace.X, cellFace.Y, cellFace.Z), 0);
					if (cellValue != (RottenMeatBlock.Index | 1 << 4 << 14))
						return false;
					inventory.RemoveSlotItems(inventory.ActiveSlotIndex, inventory.GetSlotCount(inventory.ActiveSlotIndex));
					if (inventory.GetSlotCount(inventory.ActiveSlotIndex) == 0)
						inventory.AddSlotItems(inventory.ActiveSlotIndex, RottenMeatBlock.Index | 2 << 4 << 14, 1);
					Utils.SubsystemTerrain.DestroyCell(0, cellFace.X, cellFace.Y, cellFace.Z, 0, false, false);
					return true;
				}
			}
			if (activeBlockValue == (RottenMeatBlock.Index | 2 << 4 << 14))
			{
				result2 = componentMiner.Raycast<TerrainRaycastResult>(ray,RaycastMode.Interaction);
				if (result2.HasValue && componentMiner.Place(result2.Value, RottenMeatBlock.Index | 1 << 4 << 14))
				{
					inventory.RemoveSlotItems(inventory.ActiveSlotIndex, 1);
					if (inventory.GetSlotCount(inventory.ActiveSlotIndex) == 0)
						inventory.AddSlotItems(inventory.ActiveSlotIndex, Terrain.ReplaceContents(activeBlockValue, 90), 1);
					return true;
				}
			}
			if (activeBlockValue == (RottenMeatBlock.Index | 6 << 4 << 14))
			{
				result2 = componentMiner.Raycast<TerrainRaycastResult>(ray, RaycastMode.Interaction);
				if (result2.HasValue && componentMiner.Place(result2.Value, RottenMeatBlock.Index | 6 << 4 << 14))
				{
					inventory.RemoveSlotItems(inventory.ActiveSlotIndex, 1);
					if (inventory.GetSlotCount(inventory.ActiveSlotIndex) == 0)
						inventory.AddSlotItems(inventory.ActiveSlotIndex, Terrain.ReplaceContents(activeBlockValue, 90), 1);
					return true;
				}
			}
			return false;
		put:
			entity.FindComponent<ComponentBody>(true).Position = position;
			entity.FindComponent<ComponentSpawn>(true).SpawnDuration = 0f;
			Project.AddEntity(entity);
			componentMiner.RemoveActiveTool(1);
			Utils.SubsystemAudio.PlaySound("Audio/BlockPlaced", 1f, 0f, position, 3f, true);
			return true;
		}

		public override void OnCollide(CellFace cellFace, float velocity, ComponentBody componentBody)
		{
			if (cellFace.Face != 4)
				return;
			int x = cellFace.X,
				y = cellFace.Y,
				z = cellFace.Z;
			if (Terrain.ReplaceLight(Utils.Terrain.GetCellValueFast(x, y, z), 0) == ItemBlock.IdTable["Springboard"])
			{
				componentBody.ApplyImpulse(new Vector3 { Y = -velocity });
			}
		}
	}
}